/* XXX DOES NOT USE THE BUILT-IN DETECTION FUNCTION!! XXX 
alert tcp $EXTERNAL_NET $HTTP_PORTS -> $HOME_NET any (msg:"WEB-CLIENT Microsoft Fax Cover Page Editor heap corruption attempt"; flowbits:isset,file.cov; flow:to_client,established; content:"CDrawPoly"; content:"|FF FF|"; distance:-15; within:2; metadata:policy balanced-ips drop, policy security-ips drop, service http; classtype:attempted-user; reference:cve,2010-3974; reference:url,technet.microsoft.com/en-us/security/bulletin/MS11-024;)

This custom SO actually is going to be replaced by the following text rule once we can convert byte_extract to autogenned SOs --

alert tcp $EXTERNAL_NET $HTTP_PORTS -> $HOME_NET any (msg:"WEB-CLIENT Microsoft Fax Cover Page Editor heap corruption attempt"; flowbits:isset,file.cov; flow:to_client,established; content:"|FF FF|"; content:"CDrawPoly"; distance:4; within:9; byte_extract:2,54,nAllocPoints,relative,little; byte_test:2,>,nAllocPoints,52,relative,little; metadata:policy balanced-ips drop, policy security-ips drop, service http; classtype:attempted-user; reference:cve,2010-3974; reference:url,technet.microsoft.com/en-us/security/bulletin/MS11-024;)

*/
/*
 * Vuln Title: XXXX
 *
 * Copyright (C) 2005-2010 Sourcefire, Inc. All Rights Reserved
 *
 * Written by XXXX, Sourcefire VRT <XXXX@sourcefire.com>
 *
 * Auto-generated by XXXX
 *
 * This file may contain proprietary rules that were created, tested and
 * certified by Sourcefire, Inc. (the "VRT Certified Rules") as well as
 * rules that were created by Sourcefire and other third parties and
 * distributed under the GNU General Public License (the "GPL Rules").  The
 * VRT Certified Rules contained in this file are the property of
 * Sourcefire, Inc. Copyright 2005 Sourcefire, Inc. All Rights Reserved.
 * The GPL Rules created by Sourcefire, Inc. are the property of
 * Sourcefire, Inc. Copyright 2002-2005 Sourcefire, Inc. All Rights
 * Reserved.  All other GPL Rules are owned and copyrighted by their
 * respective owners (please see www.snort.org/contributors for a list of
 * owners and their respective copyrights).  In order to determine what
 * rules are VRT Certified Rules or GPL Rules, please refer to the VRT
 * Certified Rules License Agreement.
 */

#include "sf_snort_plugin_api.h"
#include "sf_snort_packet.h"

#include "so-util.h"

/* declare detection functions */
int rule18673eval(void *p);
int rule21352eval(void *p);
int CVE_2010_3974_eval(void *p);

#ifndef MISSINGFILEDATA
/* declare rule data structures */
/* flowbits:isset "file.cov"; */
static FlowBitsInfo rule18673flowbits0 =
{
    "file.cov",
    FLOWBIT_ISSET,
    0,
};

static RuleOption rule18673option0 =
{
    OPTION_TYPE_FLOWBIT,
    {
        &rule18673flowbits0
    }
};
/* flow:established, to_client; */
static FlowFlags rule18673flow1 = 
{
    FLOW_ESTABLISHED|FLOW_TO_CLIENT
};

static RuleOption rule18673option1 =
{
    OPTION_TYPE_FLOWFLAGS,
    {
        &rule18673flow1
    }
};
// content:"CDrawPoly", depth 0, fast_pattern; 
static ContentInfo rule18673content2 = 
{
    (uint8_t *) "CDrawPoly", /* pattern (now in snort content format) */
    0, /* depth */
    0, /* offset */
    CONTENT_FAST_PATTERN|CONTENT_BUF_NORMALIZED, /* flags */
    NULL, /* holder for boyer/moore PTR */
    NULL, /* more holder info - byteform */
    0, /* byteform length */
    0 /* increment length*/
};

static RuleOption rule18673option2 = 
{
    OPTION_TYPE_CONTENT,
    {
        &rule18673content2
    }
};
// content:"|FF FF|", offset -15, depth 2, relative; 
static ContentInfo rule18673content3 = 
{
    (uint8_t *) "|FF FF|", /* pattern (now in snort content format) */
    2, /* depth */
    -15, /* offset */
    CONTENT_RELATIVE|CONTENT_BUF_NORMALIZED, /* flags */
    NULL, /* holder for boyer/moore PTR */
    NULL, /* more holder info - byteform */
    0, /* byteform length */
    0 /* increment length*/
};

static RuleOption rule18673option3 = 
{
    OPTION_TYPE_CONTENT,
    {
        &rule18673content3
    }
};

static CursorInfo rule18673cursor4 =
{
   0,
   CONTENT_BUF_NORMALIZED
};

static RuleOption rule18673option4 =
{
   OPTION_TYPE_FILE_DATA,
   {
      &rule18673cursor4
   }
};
#else

static ContentInfo rule18673content0 =
{
    (uint8_t *) "56u89werm0t89surmet89 vw4me598w74560247356we8yrn897ryenw84046556w4etrqw489raw47895qw34562356sdr", /* pattern (now in snort content format) */
    0, /* depth */
    0, /* offset */
    CONTENT_FAST_PATTERN|CONTENT_BUF_NORMALIZED, /* flags */
    NULL, /* holder for boyer/moore PTR */
    NULL, /* more holder info - byteform */
    0, /* byteform length */
    0 /* increment length*/
};

static RuleOption rule18673_DELETED =
{
    OPTION_TYPE_CONTENT,
    {
        &rule18673content0
    }
};

#endif

/* references for sid 18673 */
/* reference: cve "2010-3974"; */
static RuleReference rule18673ref1 = 
{
    "cve", /* type */
    "2010-3974" /* value */
};

/* reference: url "technet.microsoft.com/en-us/security/bulletin/MS11-024"; */
static RuleReference rule18673ref2 = 
{
    "url", /* type */
    "technet.microsoft.com/en-us/security/bulletin/MS11-024" /* value */
};

static RuleReference *rule18673refs[] =
{
    &rule18673ref1,
    &rule18673ref2,
    NULL
};
/* metadata for sid 18673 */
/* metadata:service http, policy balanced-ips drop, policy security-ips drop; */
static RuleMetaData rule18673service1 = 
{
    "service http"
};


//static RuleMetaData rule18673policy1 = 
//{
//    "policy balanced-ips drop"
//};
//
//static RuleMetaData rule18673policy2 = 
//{
//    "policy security-ips drop"
//};

static RuleMetaData rule18673policy3 = 
{
    "policy max-detect-ips drop"
};

static RuleMetaData *rule18673metadata[] =
{
    &rule18673service1,
//    &rule18673policy1,
//    &rule18673policy2,
    &rule18673policy3,
    NULL
};

RuleOption *rule18673options[] =
{
#ifndef MISSINGFILEDATA
    &rule18673option0,
    &rule18673option1,
    &rule18673option2,
    &rule18673option3,
    &rule18673option4,
#else
    &rule18673_DELETED,
#endif
    NULL
};

Rule rule18673 = {
   /* rule header, akin to => tcp any any -> any any */
   {
       IPPROTO_TCP, /* proto */
       "$EXTERNAL_NET", /* SRCIP     */
       "$FILE_DATA_PORTS", /* SRCPORT   */
       0, /* DIRECTION */
       "$HOME_NET", /* DSTIP     */
       "any", /* DSTPORT   */
   },
   /* metadata */
   { 
       3,  /* genid */
       18673, /* sigid */
       7, /* revision */
       "attempted-user", /* classification */
       0,  /* hardcoded priority XXX NOT PROVIDED BY GRAMMAR YET! */
#ifndef MISSINGFILEDATA
       "OS-WINDOWS Microsoft Fax Cover Page Editor heap corruption attempt",     /* message */
#else
       "DELETED OS-WINDOWS Microsoft Fax Cover Page Editor heap corruption attempt", /* message */
#endif
       rule18673refs /* ptr to references */
       ,rule18673metadata
   },
   rule18673options, /* ptr to rule options */
   &rule18673eval, /* use the built in detection function */
#ifndef MISSINGFILEDATA
   0 /* am I initialized yet? */
#else
   1 /* fake initialization */
#endif
};

/* flow:established, to_client; */
static FlowFlags rule21352flow1 =
{
    FLOW_ESTABLISHED|FLOW_TO_SERVER
};

static RuleOption rule21352option1 =
{
    OPTION_TYPE_FLOWFLAGS,
    {
        &rule21352flow1
    }
};

RuleOption *rule21352options[] =
{
#ifndef MISSINGFILEDATA
    &rule18673option0,
    &rule21352option1,
    &rule18673option2,
    &rule18673option3,
    &rule18673option4,
#else
    &rule18673_DELETED,
#endif
    NULL
};


Rule rule21352 = {
   /* rule header, akin to => tcp any any -> any any */
   {
       IPPROTO_TCP, /* proto */
       "$EXTERNAL_NET", /* SRCIP     */
       "any", /* SRCPORT   */
       0, /* DIRECTION */
       "$HOME_NET", /* DSTIP     */
       "25", /* DSTPORT   */
   },
   /* metadata */
   {
       3,  /* genid */
       21352, /* sigid */
       5, /* revision */
       "attempted-user", /* classification */
       0,  /* hardcoded priority XXX NOT PROVIDED BY GRAMMAR YET! */
#ifndef MISSINGFILEDATA
       "OS-WINDOWS Microsoft Fax Cover Page Editor heap corruption attempt",     /* message */
#else
       "DELETED OS-WINDOWS Microsoft Fax Cover Page Editor heap corruption attempt",     /* message */
#endif 
       rule18673refs /* ptr to references */
       ,rule18673metadata
   },
   rule21352options, /* ptr to rule options */
   &rule21352eval, /* use the built in detection function */
#ifndef MISSINGFILEDATA
   0 /* am I initialized yet? */
#else
  1 /* fake initialization */
#endif
};

int CVE_2010_3974_eval(void *p) {

#ifndef MISSINGFILEDATA
    const uint8_t *cursor_normal = 0;
    SFSnortPacket *sp = (SFSnortPacket *) p;

    const uint8_t *beg_of_payload, *end_of_payload;

    uint16_t nAllocPoints, nPoints;

    // Shift into file_data
    if(fileData(p, rule18673options[4]->option_u.cursor, &cursor_normal) <= 0) {
        return RULE_NOMATCH;
    }

   // content:"CDrawPoly", depth 0, fast_pattern;
   if (contentMatch(p, rule18673options[2]->option_u.content, &cursor_normal) > 0) {
       // content:"|FF FF|", offset -15, depth 2, relative;
       if (contentMatch(p, rule18673options[3]->option_u.content, &cursor_normal) > 0) {

           if(getBuffer(sp, CONTENT_BUF_NORMALIZED, &beg_of_payload, &end_of_payload) <= 0)
              return RULE_NOMATCH;

           if(cursor_normal + 69 > end_of_payload)
              return RULE_NOMATCH;

           nPoints = read_little_16(cursor_normal+65);
           nAllocPoints = read_little_16(cursor_normal+67);

           //fprintf(STDERR, "nPoints(%d) > nAllocPoints(%d)?\n", nPoints, nAllocPoints);
           if (nPoints > nAllocPoints)
              return RULE_MATCH;
       }
   }
#endif

   return RULE_NOMATCH;
}

/* detection functions */
// #if 0 // Don't compile the detection functions if they're not used
int rule18673eval(void *p) {
    SFSnortPacket *sp = (SFSnortPacket *) p;

    if(sp == NULL)
        return RULE_NOMATCH;

    if(sp->payload == NULL)
        return RULE_NOMATCH;
    
    // flowbits:isset "file.cov";
    if (processFlowbits(p, rule18673options[0]->option_u.flowBit) > 0) {
            // flow:established, to_client;
        if (checkFlow(p, rule18673options[1]->option_u.flowFlags) > 0 ) {
            return CVE_2010_3974_eval(p);
        }
    }
    return RULE_NOMATCH;
}

int rule21352eval(void *p) {
    SFSnortPacket *sp = (SFSnortPacket *) p;

    if(sp == NULL)
        return RULE_NOMATCH;

    if(sp->payload == NULL)
        return RULE_NOMATCH;

    // flowbits:isset "file.cov";
// BP pcap doesn't set the file name in the SMTP payload, so no flowbit will be set
//    if (processFlowbits(p, rule21352options[0]->option_u.flowBit) > 0) {
            // flow:established, to_client;
        if (checkFlow(p, rule21352options[1]->option_u.flowFlags) > 0 ) {
            return CVE_2010_3974_eval(p);
        }
//    }
    return RULE_NOMATCH;
}

// #endif // 0 Don't compile the detection functions if they're not used
/*
Rule *rules[] = {
    &rule18673,
    NULL
};
*/

